package com.stylefeng.guns.gateway.modular.order;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.rpc.RpcContext;
import com.baomidou.mybatisplus.plugins.Page;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.stylefeng.guns.api.alipay.AlipayServiceApi;
import com.stylefeng.guns.api.alipay.vo.AlipayInfoVO;
import com.stylefeng.guns.api.alipay.vo.AlipayResultVO;
import com.stylefeng.guns.api.order.OrderServiceApi;
import com.stylefeng.guns.api.order.vo.OrderVO;
import com.stylefeng.guns.core.util.TokenBucket;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.gateway.common.CurrentUser;
import com.stylefeng.guns.gateway.modular.vo.ResponseVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * @auther: madison
 * @date: 2018/11/12 21:53
 * @description:
 */
@Slf4j
@RestController
@RequestMapping("/order/")
public class OrderController {

    public static final String IMG_PRE = "http://img.meetingshop.cn";

    @Reference(interfaceClass = OrderServiceApi.class, check = false, group = "order2018", filter = "tracing")
    private OrderServiceApi orderServiceApi;

    @Reference(interfaceClass = OrderServiceApi.class, check = false, group = "order2017")
    private OrderServiceApi orderServiceApi2017;

    @Reference(interfaceClass = AlipayServiceApi.class, check = false, filter = "tracing")
    private AlipayServiceApi alipayServiceApi;

    private static TokenBucket tokenBucket = new TokenBucket();

    /**
     * 购票
     * Hystrix 有信号量隔离
     *         ThreadLocal 隔离
     *         线程切换
     * @param fieldId
     * @param soldSeats
     * @param seatsName
     * @return
     */
    @HystrixCommand(fallbackMethod = "error", commandProperties = {
            @HystrixProperty(name="execution.isolation.strategy", value = "THREAD"),
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value
                    = "4000"),
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50")
        }, threadPoolProperties = {
            @HystrixProperty(name = "coreSize", value = "1"),
            @HystrixProperty(name = "maxQueueSize", value = "10"),
            @HystrixProperty(name = "keepAliveTimeMinutes", value = "1000"),
            @HystrixProperty(name = "queueSizeRejectionThreshold", value = "8"),
            @HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "12"),
            @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "1500")
        })
    @RequestMapping(value = "/buyTickets", method = RequestMethod.POST)
    public ResponseVO buyTickets(Integer fieldId, String soldSeats, String seatsName){
        if(tokenBucket.getToken()){
            // 验证售出的票是否为真
            boolean trueSeats = orderServiceApi.isTrueSeats(fieldId + "", soldSeats);
            // 已经销售的座位里，有没有这些座位
            boolean notSoldSeats = orderServiceApi.isNotSoldSeats(fieldId + "", soldSeats);

            // 验证 上述两个内容有一个不为真，则不创建订单信息
            if(trueSeats && notSoldSeats){
                // 创建订单信息
                String userId = CurrentUser.getCurrentUser();
                if(userId == null || userId.trim().length() == 0){
                    return ResponseVO.serviceFail("用户未登陆");
                }
                OrderVO orderVO = orderServiceApi.saveOrderInfo(fieldId, soldSeats, seatsName, Integer.parseInt(userId));
                if(orderVO == null){
                    log.error("购票未成功");
                    return ResponseVO.serviceFail("购票业务异常");
                }
                return ResponseVO.success(orderVO);
            }else{
                return ResponseVO.serviceFail("订单中的座位编号有问题");
            }
        }else{
            return ResponseVO.serviceFail("购票人数过多，请稍后再试");
        }

    }

    @RequestMapping(value = "getOrderInfo", method = RequestMethod.POST)
    public ResponseVO getOrderInfo(
            @RequestParam(value = "nowPage",required = false,defaultValue = "1")Integer nowPage,
            @RequestParam(value = "pageSize", required = false, defaultValue = "5")Integer pageSize){

        // 获取当前登陆人的信息
        String userId = CurrentUser.getCurrentUser();
        // 使用当前登陆人获取已经购买的订单
        if(userId != null && userId.trim().length()>0){
            Page<OrderVO> page = new Page<>(nowPage, pageSize);
            Page<OrderVO> result = orderServiceApi.getOrderByUserId(Integer.parseInt(userId), page);
            Page<OrderVO> result2017 = orderServiceApi2017.getOrderByUserId(Integer.parseInt(userId), page);
            int totalPages = (int)(result.getPages() + result2017.getPages());
            // 2017和2018的订单总数
            List<OrderVO> orderVOList = new ArrayList<>();
            orderVOList.addAll(result.getRecords());
            orderVOList.addAll(result2017.getRecords());
//            return ResponseVO.success(nowPage, (int)result.getPages(), "", result.getRecords());
            return ResponseVO.success(nowPage, totalPages, "", orderVOList);
        }else{
            return ResponseVO.serviceFail("用户未登陆");
        }
    }

    @RequestMapping(value = "getPayInfo", method = RequestMethod.POST)
    public ResponseVO getPayInfo(@RequestParam("orderId") String orderId){
        // 获取当前登陆人的信息
        String userId = CurrentUser.getCurrentUser();
        if(StringUtils.isEmpty(userId)){
            return ResponseVO.serviceFail("抱歉，用户未登陆");
        }

        // 订单二维码返回结果
        AlipayInfoVO alipayInfoVO = alipayServiceApi.getQRCode(orderId);
        return ResponseVO.success(IMG_PRE, alipayInfoVO);
    }

    @RequestMapping(value = "getPayResult", method = RequestMethod.POST)
    public ResponseVO getPayResult(@RequestParam("orderId") String orderId, @RequestParam(value = "tryNums", required = false, defaultValue = "1")Integer tryNums){
        // 获取当前登陆人的信息
        String userId = CurrentUser.getCurrentUser();
        if(StringUtils.isEmpty(userId)){
            return ResponseVO.serviceFail("抱歉，用户未登陆");
        }

        // 将当前登陆人的信息传递后后端
        RpcContext.getContext().setAttachment("userId", userId);

        // 判断是否支付超时
        if(tryNums > 4){
            return ResponseVO.serviceFail("订单支付失败，请稍后重试");
        }
        AlipayResultVO alipayResultVO = alipayServiceApi.getOrderStatus(orderId);
        if(alipayResultVO == null || ToolUtil.isEmpty(alipayResultVO.getOrderId())){
            AlipayResultVO serviceFailVO = new AlipayResultVO();
            serviceFailVO.setOrderId(orderId);
            serviceFailVO.setOrderStatus(0);
            serviceFailVO.setOrderMsg("支付不成功");
            return ResponseVO.success(serviceFailVO);
        }
        return ResponseVO.success(alipayResultVO);
    }

    public ResponseVO error(Integer fieldId, String soldSeats, String seatsName){
        return ResponseVO.serviceFail("抱歉，下单的人太多了，请稍后再试");
    }
}
